//
//    Copyright (C) 2012  OinkStudio
//
//    This program is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    This program is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
package game;

public class IAHard extends CPU {
	private Game game;
	private Obolo[][] originalBoard;
	private Obolo[][] board;
	private CPU player1;
	private CPU player2;
	private Obolo[] hisDeckCopy;
	private Obolo[] myDeckCopy;
	private Obolo inCourse;
	private Obolo[] myDeck;
	private int parameter = 1;
	private IAOboloHelp possResult;

	public void setBoard(Obolo[][] boardToCopy)
			throws CloneNotSupportedException {
		for (int r = 0; r < board.length; r++) {
			for (int c = 0; c < board[0].length; c++) {
				this.board[r][c] = boardToCopy[r][c].clone();
			}
		}
	}

	public IAHard(String name) {
		super(name);
	}

	public IAOboloHelp bestOption(Game gameOriginal) {

		inicializeAndCloneGame(gameOriginal);

		for (int numObolo = 0; numObolo < myDeck.length; numObolo++) {
			try {
				if (myDeck[numObolo] != null)// {
					inCourse = myDeck[numObolo].clone();
				// System.out.println(inCourse.toString() +
				// " nombre de obolo = "+numObolo);}
				else
					inCourse = null;
			} catch (CloneNotSupportedException e) {

			}
			if (inCourse != null) {
				for (int row = 0; row < originalBoard.length; row++)
					for (int col = 0; col < originalBoard[0].length; col++) {

						parameter = 1;
						copyBoard(gameOriginal.getBoard());
						if (originalBoard[row][col] == null) {
							game.getBoard()[row][col] = inCourse;
							// game.changeTurn();
							fillBoard();
							copyDeck(myDeckCopy, game.getPlayerDeck(Game.RIVAL));
							copyDeck(hisDeckCopy, game.getPlayerDeck(Game.USER));
							game.setBoard(originalBoard);

							if (possResult.parameter < parameter) {
								possResult.obolo = gameOriginal
										.getPlayerDeck(gameOriginal.getTurn())[numObolo];
								possResult.parameter = parameter;
								possResult.column = col;
								possResult.row = row;
							}
						}

					}
			}
		}
		game.setBoard(originalBoard);
		gameOriginal.setBoard(originalBoard);
		originalSituation();

		return possResult;
	}

	private void fillBoard() {
		Obolo[] deck;
		// boolean acabar = false;
		deck = game.getPlayer(game.getTurn()).getDeck();

		if (!game.isFinish()) {
			for (int indexDeck = 0; indexDeck < deck.length; indexDeck++) {
				// for (Obolo obolo : deck)
				// game.setBoard(originalBoard);
				if (deck[indexDeck] != null) {
					Obolo obolo = null;
					try {
						obolo = deck[indexDeck].clone();

					} catch (CloneNotSupportedException e) {
						e.printStackTrace();
					}

					game.getPlayer(game.getTurn()).removeOboloFromDeck(obolo);
					for (int row = 0; row < board.length; row++)
						for (int col = 0; col < board[0].length; col++) {

							if (obolo != null
									&& game.getBoard()[row][col] == null) {
								// System.out.println(parameter + " parameter "
								// + row + " row " + col +" col "+
								// obolo.toString()+ " owner " +
								// obolo.getOwner()+" "+ game.getTurn());

								game.putObolo(row, col, obolo);

								if (!game.isFinish()) {
									fillBoard();

									System.out
											.println("Trec obolo i el poso al deck");

								} else if (game.whoWin() == game
										.getPlayer(Game.RIVAL))
									++parameter;
								game.changeTurn();
								// deck[indexDeck] = game.getBoard()[row][col];
								game.getBoard()[row][col].setOwner(game
										.getTurn());
								game.getBoard()[row][col] = null;

							}
						}
				}
			}
		}
		// return parameter;

	}

	private static void copyDeck(Obolo[] deck, Obolo[] copyDeck) {
		// copyDeck = new Obolo[deck.length];
		for (int i = 0; i < deck.length; i++) {
			try {
				if (deck[i] != null)
					copyDeck[i] = deck[i].clone();
			} catch (Exception e) {
				System.out.println("clone deck errorr!!!");
			}
		}
	}

	private void copyBoard(Obolo[][] boardGame) {
		originalBoard = boardGame;
		board = new Obolo[originalBoard.length][originalBoard[0].length];
		for (int i = 0; i < board.length; i++)
			for (int j = 0; j < board[0].length; j++) {
				try {
					if (originalBoard[i][j] != null) {
						board[i][j] = originalBoard[i][j].clone();
					}
				} catch (CloneNotSupportedException e) {
					System.out.println("clone board errorr!!!");
				}
			}
		game.setBoard(board);
	}

	private void originalSituation() {
		game.setBoard(originalBoard);
		game.getPlayer(0).setDeck(myDeckCopy);
		game.getPlayer(1).setDeck(hisDeckCopy);
	}

	public void inicializeAndCloneGame(Game gameOriginal) {
		possResult = new IAOboloHelp();
		game = new Game(gameOriginal.getRowNumber(), gameOriginal
				.getColumnNumber(), gameOriginal.getBlank());
		player1 = new IAHard("1");
		player2 = new IAHard("0");
		myDeck = new Obolo[gameOriginal.getPlayerDeck(0).length];
		copyDeck(gameOriginal.getPlayerDeck(0), myDeck);
		player1.setDeck(myDeck);
		Obolo[] hisDeck = new Obolo[gameOriginal.getPlayerDeck(1).length];
		copyDeck(gameOriginal.getPlayerDeck(1), hisDeck);
		player2.setDeck(hisDeck);
		game.setRules(gameOriginal.getRules());
		game.setPlayers(player1, player2);
		// originalBoard = gameOriginal.getBoard();
		copyBoard(gameOriginal.getBoard());
		game.setBoard(board);
		myDeckCopy = new Obolo[game.getPlayer(0).getDeck().length];
		hisDeckCopy = new Obolo[game.getPlayer(1).getDeck().length];
		copyDeck(game.getPlayer(0).getDeck(), myDeckCopy);
		copyDeck(game.getPlayer(1).getDeck(), hisDeckCopy);
	}

}
